'''
    表格读取模块
    
    使用pandas模块对表格进行读取。
    读取方式分为：
    1. 迭代行：一行一行读取，知道读取结束
    2. 迭代列：一列一列读取，知道结束
    3. 固定行：只读取特定一行
    4. 固定列：只读取特定一列


'''

from pyx_package.script import BaseBehavior
from pyx_package.ps_paramete import PsParameter

import os
import pandas as pd

PYX_MODULE_NAME = "read-excel"

import sys
import traceback

def GetExceptStr():
    '''
        获取异常字符串
    '''

    msg = ""
    for line in traceback.TracebackException(
        type(sys.exc_info()[1]), sys.exc_info()[1], sys.exc_info()[2]).format():
        msg += line + "\n"

    return msg

class ScriptBehavior(BaseBehavior):

    class OuputType:
        
        IterRow = '行迭代式 -> list'
        IterColumn = '列迭代式 -> list'
        FixRow = '指定行 -> list'
        FixColumn = '指定列 -> list'

    def __init__(self) -> None:
        super().__init__()
        
        self.SetExeMode("iter")
        self.InitVars()

        
        self.InitInputParams()
        self.InitOutputParams()
    
    def InitVars(self):

        #表格数据
        self._excel_data = None

        #记录当前索引
        self._curr_row = 0

        #当前状态 True表示正常，False表示不正常
        self._error = False

    def InitInputParams(self):
        #路径
        self.p_path = self.CreateParam("path", "文件路径", PsParameter.Input, str, "")

        #表单
        self.p_sheet = self.CreateParam("sheet", "页名", PsParameter.Input, str, "")
        self.p_sheet.keep_value = False
        self.p_sheet.must = False

        #固定行列的参数
        self.p_fix_index = self.CreateParam("fix index", "指定行/列", PsParameter.Input, int, 0)
        self.p_fix_index.hide = True
        self.p_fix_index.must = False

        #输出方式
        self.p_output_type = self.CreateParam("output type", "输出格式", PsParameter.Input, str, "")
        self.p_output_type.value_input_mode = PsParameter.ComboBoxMode
        self.p_output_type.SetValueChangedFunc("CallOutputTypeChanged")
        self.p_output_type.SetOptionitems([
            self.OuputType.IterRow,
            self.OuputType.IterColumn,
            self.OuputType.FixRow,
            self.OuputType.FixColumn,
        ])
        self.p_output_type.must = False

        #读取配置
        self.p_file_config = self.CreateParam("file config", "读取配置", PsParameter.Input, None)

        #标题行
        self.p_header_row = self.CreateParam("header row", "标题所在行", PsParameter.Input, int, 0)
        self.p_file_config.AddChild(self.p_header_row)
        self.p_header_row.must = False

    def InitOutputParams(self):

        self.p_row_count = self.CreateParam("read row count", "读取的总行数", PsParameter.Output, int, -1)
        self.p_column_count = self.CreateParam("read column count", "读取的总列数", PsParameter.Output, int, -1)
        
        #输出内容
        self.p_content = self.CreateParam("output content", "输出数据", PsParameter.Output, list, [])
        
        #当前输出的索引值
        self.p_out_index = self.CreateParam("output index", "当前数据的索引", PsParameter.Output, int, 0)

    def CallOutputTypeChanged(self):
        '''
            当输出模式改变后触发
        '''

        if self.IsIter():

            self.p_fix_index.hide = True

        else:
            self.p_fix_index.hide = False
            
    def IsIter(self):
        '''
            判断当前模式是否需要迭代
        '''

        if self.p_output_type.value == self.OuputType.FixColumn or \
            self.p_output_type.value == self.OuputType.FixRow:
            return False

        else:
            return True

    def FirstStep(self):
        '''
            第一次执行时读取
        '''

        #获取sheet
        sheet_name = self.p_sheet.value

        #表头信息
        header = None if self.p_header_row.value < 0 else self.p_header_row.value

        #判断路径是否存在
        if not os.path.exists(self.p_path.value):
            self.Debug("文件路径不存在:" + self.p_path.value, "error")
            self._error = True
            return
        
        try:
            if sheet_name == "" or sheet_name == "None":
                self._excel_data = pd.read_excel(self.p_path.value, header = header)

            else:
                self._excel_data = pd.read_excel(self.p_path.value, header = header, sheet_name=sheet_name)

        except:
            self.Debug("文件加载失败 : " + GetExceptStr(), "error")
            self._error = True
            return
        
        #获取总行数和列数
        self.p_row_count.value, self.p_column_count.value = self._excel_data.shape

        #如果行列小于0则此模块不处理任何事物
        if self.p_row_count.value <= 0 or self.p_column_count.value <= 0:
            self.Debug("表格内容为空！", "warning")
            self._error = True
            return

        else:
            self.Debug("当前表格: 行数: {}, 列数: {}".format(self.p_row_count.value, self.p_column_count.value)) 
        
        #重置索引
        self._curr_row = 0

    def DoStep(self):

        if self._error: return

        if self.p_output_type.value == self.OuputType.IterRow:
            self.DoIter()

        elif self.p_output_type.value == self.OuputType.IterColumn:
            self.DoIter(False)

        elif self.p_output_type.value == self.OuputType.FixRow:
            self.p_content.value = self._excel_data.iloc[self.p_fix_index.value,:].values
            self.p_out_index.value = self.p_fix_index.value
            self.Finish()

        elif self.p_output_type.value == self.OuputType.FixColumn:
            self.p_content.value = self._excel_data.iloc[:, self.p_fix_index.value].values
            self.p_out_index.value = self.p_fix_index.value
            self.Finish()

    def DoIter(self, is_row = True):

        if is_row:
            self.p_content.value = self._excel_data.iloc[self._curr_row,:].values

        else:
            self.p_content.value = self._excel_data.iloc[:,self._curr_row].values

        self.p_out_index.value = self._curr_row
        self._curr_row += 1

        if self._curr_row >= self.p_row_count.value:
            self._curr_row = 0
            self.Finish()

